Reading libraries and parameters
library(tidyverse)
library(quickpsy)
library(cowplot)
list.files("R", full.names = TRUE) %>% walk(source)
source("graphical_parameters.R")
source("parameters.R")
load(file = "logdata/dat2.RData")
No two guess
fun_sym_no_two_guess2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[5] + + (1 - p[5] - p[6]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[7] + (1 - p[7] - p[8]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_no_two_guess2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_no_two_guess2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale, pini_scale,
pini_lapse, pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_no_two_guess2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_no_two_guess2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

Two guess
fun_sym_two_guess2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[5] + p[7] + (1 - 2 * p[5] - p[7]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[6] + (1 - 2 * p[6] - p[7]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_two_guess2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_two_guess2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale, pini_scale,
pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_two_guess2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_two_guess2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

No two guess vs two guess
sym_no_two_guess_vs_two_guess2 <- model_selection_lrt(
fit_sym_no_two_guess2$logliks,
fit_sym_two_guess2$logliks)
sym_no_two_guess_vs_two_guess2 %>%
group_by(best) %>%
count()
best_sym_no_two_guess2 <- sym_no_two_guess_vs_two_guess2 %>%
filter(best == "first") %>%
select(subject, cond_per_block)
best_sym_two_guess2 <- sym_no_two_guess_vs_two_guess2 %>%
filter(best == "second") %>%
select(subject, cond_per_block)
No two guess same slope
fun_sym_no_two_guess_same_slope2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[4] + + (1 - p[4] - p[5]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[6] + (1 - p[6] - p[7]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_no_two_guess_same_slope2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_no_two_guess_same_slope2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale,
pini_lapse, pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_no_two_guess_same_slope2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_no_two_guess_same_slope2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

No two guess vs no two guess same slope
sym_no_two_guess_vs_no_two_guess_same_slope2 <- model_selection_lrt(
fit_sym_no_two_guess2$logliks,
fit_sym_no_two_guess_same_slope2$logliks)
sym_no_two_guess_vs_no_two_guess_same_slope2 %>%
semi_join(best_sym_no_two_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_two_guess_same_slope2 <- sym_no_two_guess_vs_no_two_guess_same_slope2 %>%
semi_join(best_sym_no_two_guess2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Sym guess
fun_sym_guess2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[6] + (1 - 2 * p[6]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_guess2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_guess2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale, pini_scale,
pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_guess2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_guess2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Sym guess vs no sym guess
sym_two_guess_vs_sym_guess2 <- model_selection_lrt(
fit_sym_two_guess2$logliks,
fit_sym_guess2$logliks)
sym_two_guess_vs_sym_guess2 %>%
semi_join(best_sym_two_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_guess2 <- best_sym_two_guess2
Sym same guess
fun_sym_same_guess2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_same_guess2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess vs no same slope
sym_same_guess_vs_no_same_guess2 <- model_selection_lrt(
fit_sym_guess2$logliks,
fit_sym_same_guess2$logliks)
sym_same_guess_vs_no_same_guess2 %>%
semi_join(best_sym_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_no_same_guess2 <- sym_same_guess_vs_no_same_guess2 %>%
semi_join(best_sym_guess2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
best_sym_same_guess2 <- sym_same_guess_vs_no_same_guess2 %>%
semi_join(best_sym_guess2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
No same guess same slope
fun_sym_guess_same_slope2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_guess_same_slope2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_guess_same_slope2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale,
pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_guess_same_slope2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_guess_same_slope2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

No same guess vs no same guess same slope
sym_same_guess_vs_same_guess_same_slope2 <- model_selection_lrt(
fit_sym_guess2$logliks,
fit_sym_guess_same_slope2$logliks)
sym_same_guess_vs_same_guess_same_slope2 %>%
semi_join(best_sym_no_same_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_same_guess_same_slope2 <- best_sym_no_same_guess2
Absent lapses
fun_sym_absent_lapses2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_absent_lapses2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses vs no absent lapses
sym_absent_lapses_vs_no_absent_lapses2 <- model_selection_lrt(
fit_sym_same_guess2$logliks,
fit_sym_absent_lapses2$logliks)
sym_absent_lapses_vs_no_absent_lapses2 %>%
semi_join(best_sym_same_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_no_absent_lapses2 <- sym_absent_lapses_vs_no_absent_lapses2 %>%
semi_join(best_sym_same_guess2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
best_sym_absent_lapses2 <- sym_absent_lapses_vs_no_absent_lapses2 %>%
semi_join(best_sym_same_guess2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Sym same guess same slope
fun_sym_same_guess_same_slope2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_same_guess_same_slope2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_same_slope2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_same_slope2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_same_slope2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

No absent lapses vs no absent lapses same slope
sym_no_absent_lapses_vs_no_absent_lapses_same_slope2 <- model_selection_lrt(
fit_sym_same_guess2$logliks,
fit_sym_same_guess_same_slope2$logliks)
sym_no_absent_lapses_vs_no_absent_lapses_same_slope2 %>%
semi_join(best_sym_no_absent_lapses2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_absent_lapses_no_same_slope2 <- sym_no_absent_lapses_vs_no_absent_lapses_same_slope2 %>%
semi_join(best_sym_no_absent_lapses2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_absent_lapses_same_slope2 <- sym_no_absent_lapses_vs_no_absent_lapses_same_slope2 %>%
semi_join(best_sym_no_absent_lapses2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Absent lapses same slope
fun_sym_absent_lapses_same_slope2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] + p[2], p[3]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_absent_lapses_same_slope2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_same_slope2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_origin, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_same_slope2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_same_slope2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses vs absent lapses same slope
sym_absent_lapses_vs_absent_lapses_same_slope2 <- model_selection_lrt(
fit_sym_absent_lapses2$logliks,
fit_sym_absent_lapses_same_slope2$logliks)
sym_absent_lapses_vs_absent_lapses_same_slope2 %>%
semi_join(best_sym_absent_lapses2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_absent_lapses_no_same_slope2 <- sym_absent_lapses_vs_absent_lapses_same_slope2 %>%
semi_join(best_sym_absent_lapses2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_absent_lapses_same_slope2 <- sym_absent_lapses_vs_absent_lapses_same_slope2 %>%
semi_join(best_sym_absent_lapses2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Averages, curves and parameters (checking)
sym_averages_s_vs_d_test2 <-
(fit_sym_no_two_guess_same_slope2$averages %>% semi_join(best_sym_no_two_guess_same_slope2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_no_two_guess_same_slope2$curves %>% semi_join(best_sym_no_two_guess_same_slope2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

sym_averages_s_vs_d_test2 <-
(fit_sym_guess_same_slope2$averages %>% semi_join(best_sym_no_same_guess2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_guess_same_slope2$curves %>% semi_join(best_sym_no_same_guess2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

sym_averages_s_vs_d_test2 <-
(fit_sym_same_guess2$averages %>% semi_join(best_sym_no_absent_lapses_no_same_slope2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_same_guess2$curves %>% semi_join(best_sym_no_absent_lapses_no_same_slope2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

sym_averages_s_vs_d_test2 <-
(fit_sym_same_guess_same_slope2$averages %>% semi_join(best_sym_no_absent_lapses_same_slope2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_same_guess_same_slope2$curves %>% semi_join(best_sym_no_absent_lapses_same_slope2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

sym_averages_s_vs_d_test2 <-
(fit_sym_absent_lapses2$averages %>% semi_join(best_sym_absent_lapses_no_same_slope2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_absent_lapses2$curves %>% semi_join(best_sym_absent_lapses_no_same_slope2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

sym_averages_s_vs_d_test2 <-
(fit_sym_absent_lapses_same_slope2$averages %>% semi_join(best_sym_absent_lapses_same_slope2))
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_test2 <-
(fit_sym_absent_lapses_same_slope2$curves %>% semi_join(best_sym_absent_lapses_same_slope2))
Joining, by = c("subject", "cond_per_block")
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d_test2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d_test2,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

Averages, curves and parameters
sym_averages_s_vs_d2 <-
(fit_sym_no_two_guess_same_slope2$averages %>% semi_join(best_sym_no_two_guess_same_slope2)) %>%
bind_rows((fit_sym_guess_same_slope2$averages %>% semi_join(best_sym_no_same_guess2))) %>%
bind_rows((fit_sym_same_guess2$averages %>% semi_join(best_sym_no_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_same_guess_same_slope2$averages %>% semi_join(best_sym_no_absent_lapses_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses2$averages %>% semi_join(best_sym_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses_same_slope2$averages %>% semi_join(best_sym_absent_lapses_same_slope2)))
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d2 <-
(fit_sym_no_two_guess_same_slope2$curves %>% semi_join(best_sym_no_two_guess_same_slope2)) %>%
bind_rows((fit_sym_guess_same_slope2$curves %>% semi_join(best_sym_no_same_guess2))) %>%
bind_rows((fit_sym_same_guess2$curves %>% semi_join(best_sym_no_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_same_guess_same_slope2$curves %>% semi_join(best_sym_no_absent_lapses_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses2$curves %>% semi_join(best_sym_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses_same_slope2$curves %>% semi_join(best_sym_absent_lapses_same_slope2)))
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
sym_par_s_vs_d2 <-
(fit_sym_no_two_guess_same_slope2$par %>% semi_join(best_sym_no_two_guess_same_slope2)) %>%
bind_rows((fit_sym_guess_same_slope2$par %>% semi_join(best_sym_no_same_guess2))) %>%
bind_rows((fit_sym_same_guess2$par %>% semi_join(best_sym_no_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_same_guess_same_slope2$par %>% semi_join(best_sym_no_absent_lapses_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses2$par %>% semi_join(best_sym_absent_lapses_no_same_slope2))) %>%
bind_rows((fit_sym_absent_lapses_same_slope2$par %>% semi_join(best_sym_absent_lapses_same_slope2)))
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
Joining, by = c("subject", "cond_per_block")
sym_par_s_vs_d_long2 <- sym_par_s_vs_d2 %>%
spread(parn, par)
ggplot() + facet_wrap(subject ~ cond_per_block) +
geom_point(data = sym_averages_s_vs_d2,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = sym_curves_s_vs_d2,
aes(x = x, y = y, color = references)) +
geom_vline(data = sym_par_s_vs_d_long2,
aes(xintercept = p1, lty = "p1")) +
geom_vline(data = sym_par_s_vs_d_long2,
aes(xintercept = p1 + p2, lty = "p1 +p2")) +
theme_grey() + theme(legend.position = "top")

No two guess same slope zero
fun_sym_no_two_guess_same_slope_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[2] + + (1 - p[2] - p[3]) * pnorm(x, 0, p[1]),
function(x, p) p[4] + (1 - p[4] - p[5]) * pnorm(x, 0, p[1]))))
fit_sym_no_two_guess_same_slope_zero2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_no_two_guess_same_slope_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale,
pini_lapse, pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_no_two_guess_same_slope_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_no_two_guess_same_slope_zero2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

No two guess same slope zero vs no two guess same slope
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero2 <- model_selection_lrt(
fit_sym_no_two_guess_same_slope2$logliks,
fit_sym_no_two_guess_same_slope_zero2$logliks)
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero2 %>%
semi_join(best_sym_no_two_guess_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_no_two_guess_same_slope_no_zero2 <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero2 %>%
semi_join(best_sym_no_two_guess_same_slope2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_two_guess_same_slope_zero2 <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero2 %>%
semi_join(best_sym_no_two_guess_same_slope2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "zero")
Joining, by = c("subject", "cond_per_block")
No two guess same slope s
fun_sym_no_two_guess_same_slope_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + + (1 - p[3] - p[4]) * pnorm(x, p[1], p[2]),
function(x, p) p[5] + (1 - p[5] - p[6]) * pnorm(x, p[1], p[2]))))
fit_sym_no_two_guess_same_slope_s2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_no_two_guess_same_slope_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse, pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_no_two_guess_same_slope_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_no_two_guess_same_slope_s2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

No two guess same slope vs no two guess same slope s
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_s2 <- model_selection_lrt(
fit_sym_no_two_guess_same_slope2$logliks,
fit_sym_no_two_guess_same_slope_s2$logliks)
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_s2 %>%
semi_join(best_sym_no_two_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
No two guess same slope d
fun_sym_no_two_guess_same_slope_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + + (1 - p[3] - p[4]) * pnorm(x, p[1], p[2]),
function(x, p) p[5] + (1 - p[5] - p[6]) * pnorm(x, -p[1], p[2]))))
fit_sym_no_two_guess_same_slope_d2 <- quickpsy(dat2, orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_no_two_guess_same_slope_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse, pini_lapse, pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_no_two_guess_same_slope_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_no_two_guess_same_slope_d2$curves,
aes(x = x, y = y, color = references)) +
theme_grey() + theme(legend.position = "top")

No two guess same slope vs no two guess same slope d
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d2 <- model_selection_lrt(
fit_sym_no_two_guess_same_slope2$logliks,
fit_sym_no_two_guess_same_slope_d2$logliks)
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d2 %>%
semi_join(best_sym_no_two_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_no_two_guess_same_slope_no_zero_full2 <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d2 %>%
semi_join(best_sym_no_two_guess_same_slope_no_zero2) %>%
filter(best == "first") %>%
select(subject, cond_per_block) %>%
mutate(best = "full")
Joining, by = c("subject", "cond_per_block")
No same guess same slope zero
fun_sym_guess_same_slope_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]),
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[1]))))
fit_sym_guess_same_slope_zero2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_guess_same_slope_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale,
pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_guess_same_slope_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_guess_same_slope_zero2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

No same guess same slope vs no same guess same slope zero
sym_guess_same_slope_vs_sym_guess_same_slope_zero2 <- model_selection_lrt(
fit_sym_guess_same_slope2$logliks,
fit_sym_guess_same_slope_zero2$logliks)
sym_guess_same_slope_vs_sym_guess_same_slope_zero2 %>%
semi_join(best_sym_no_same_guess2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_guess_same_slope_no_zero2 <- sym_guess_same_slope_vs_sym_guess_same_slope_zero2 %>%
semi_join(best_sym_no_same_guess2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
No same guess same slope s
fun_sym_guess_same_slope_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]),
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]))))
fit_sym_guess_same_slope_s2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_guess_same_slope_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_guess_same_slope_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_guess_same_slope_s2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

No same guess same slope no zero vs no same guess same slope no zero s
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s2 <- model_selection_lrt(
fit_sym_guess_same_slope2$logliks,
fit_sym_guess_same_slope_s2$logliks)
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_guess_same_slope_no_zero_no_s2 <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_guess_same_slope_no_zero2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
best_sym_guess_same_slope_no_zero_s2 <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_guess_same_slope_no_zero2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
No same guess same slope d
fun_sym_guess_same_slope_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]),
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, -p[1], p[2]))))
fit_sym_guess_same_slope_d2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_guess_same_slope_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse, pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_guess_same_slope_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_guess_same_slope_d2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

No same guess same slope no zero vs no same guess same slope no zero d
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d2 <- model_selection_lrt(
fit_sym_guess_same_slope2$logliks,
fit_sym_guess_same_slope_d2$logliks)
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d2 %>%
semi_join(best_sym_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_guess_same_slope_no_zero_full2 <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d2 %>%
semi_join(best_sym_guess_same_slope_no_zero2) %>%
filter(best == "first") %>%
select(subject, cond_per_block) %>%
mutate(best = "full")
Joining, by = c("subject", "cond_per_block")
Sym same guess no same slope zero
fun_sym_same_guess_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[1]),
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[2]))))
fit_sym_same_guess_zero2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_zero2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess no same slope no zero vs Same guess no same slope zero
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero2 <- model_selection_lrt(
fit_sym_same_guess2$logliks,
fit_sym_same_guess_zero2$logliks)
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero2 %>%
semi_join(best_sym_no_absent_lapses_no_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_same_guess_no_same_slope_no_zero <- sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero2 %>%
semi_join(best_sym_no_absent_lapses_no_same_slope2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_same_guess_no_same_slope_zero2 <- sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero2 %>%
semi_join(best_sym_no_absent_lapses_no_same_slope2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "zero")
Joining, by = c("subject", "cond_per_block")
Sym same guess no same slope no zero s
fun_sym_same_guess_no_zero_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]),
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[3]))))
fit_sym_same_guess_no_zero_s2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_no_zero_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_no_zero_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_no_zero_s2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess no same slope no zero vs Same guess no same slope no zero s
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s2 <- model_selection_lrt(
fit_sym_same_guess2$logliks,
fit_sym_same_guess_no_zero_s2$logliks)
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s2 %>%
semi_join(best_sym_same_guess_no_same_slope_no_zero) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
Sym same guess no same slope no zero d
fun_sym_same_guess_no_zero_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]),
function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, -p[1], p[3]))))
fit_sym_same_guess_no_zero_d2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_no_zero_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_no_zero_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_no_zero_d2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess no same slope no zero vs Same guess no same slope no zero d
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_d2 <- model_selection_lrt(
fit_sym_same_guess2$logliks,
fit_sym_same_guess_no_zero_d2$logliks)
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_d2%>%
semi_join(best_sym_same_guess_no_same_slope_no_zero) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_same_guess_no_same_slope_no_zero_s2 <- sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_d2 %>%
semi_join(best_sym_same_guess_no_same_slope_no_zero) %>%
filter(best == "first") %>%
select(subject, cond_per_block) %>%
mutate(best = "sensory")
Joining, by = c("subject", "cond_per_block")
Sym same guess same slope zero
fun_sym_same_guess_same_slope_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]),
function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]))))
fit_sym_same_guess_same_slope_zero2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_same_slope_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_same_slope_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_same_slope_zero2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess same slope no zero vs same guess same slope zero
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero2 <- model_selection_lrt(
fit_sym_same_guess_same_slope2$logliks,
fit_sym_same_guess_same_slope_zero2$logliks)
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero2 %>%
semi_join(best_sym_no_absent_lapses_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_same_guess_same_slope_no_zero2 <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero2 %>%
semi_join(best_sym_no_absent_lapses_same_slope2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Sym same guess same slope no zero s
fun_sym_same_guess_same_slope_no_zero_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]),
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]))))
fit_sym_same_guess_same_slope_no_zero_s2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_same_slope_no_zero_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_same_slope_no_zero_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_same_slope_no_zero_s2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess same slope no zero vs same guess same slope no zero s
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s2 <- model_selection_lrt(
fit_sym_same_guess_same_slope2$logliks,
fit_sym_same_guess_same_slope_no_zero_s2$logliks)
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_same_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
Sym same guess same slope no zero d
fun_sym_same_guess_same_slope_no_zero_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]),
function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, -p[1], p[2]))))
fit_sym_same_guess_same_slope_no_zero_d2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_same_guess_same_slope_no_zero_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale,
pini_lapse),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_same_guess_same_slope_no_zero_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_same_guess_same_slope_no_zero_d2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Same guess same slope no zero vs same guess same slope no zero d
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_d2 <- model_selection_lrt(
fit_sym_same_guess_same_slope2$logliks,
fit_sym_same_guess_same_slope_no_zero_d2$logliks)
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_d2 %>%
semi_join(best_sym_same_guess_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_same_guess_same_slope_no_zero_full2 <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_same_guess_same_slope_no_zero2) %>%
filter(best == "first") %>%
select(subject, cond_per_block) %>%
mutate(best = "full")
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_same_guess_same_slope_no_zero_s2 <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s2 %>%
semi_join(best_sym_same_guess_same_slope_no_zero2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "sensory")
Joining, by = c("subject", "cond_per_block")
Absent lapses no same slope zero
fun_sym_absent_lapses_no_same_slope_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[2]))))
fit_sym_absent_lapses_no_same_slope_zero2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_no_same_slope_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_no_same_slope_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_no_same_slope_zero2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses no same slope vs absent lapses no same slope zero
sym_absent_lapses_no_same_slope_vs_absent_lapses_no_same_slope_zero2 <- model_selection_lrt(
fit_sym_absent_lapses2$logliks,
fit_sym_absent_lapses_no_same_slope_zero2$logliks)
sym_absent_lapses_no_same_slope_vs_absent_lapses_no_same_slope_zero2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
Absent lapses no same slope no zero s
fun_sym_absent_lapses_no_same_slope_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[3]))))
fit_sym_absent_lapses_no_same_slope_s2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_no_same_slope_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_no_same_slope_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_no_same_slope_s2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses no same slope no zero vs absent lapses no same slope no zero s
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s2 <- model_selection_lrt(
fit_sym_absent_lapses2$logliks,
fit_sym_absent_lapses_no_same_slope_s2$logliks)
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_sym_absent_lapses_no_same_slope_no_zero_no_s2 <- sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_absent_lapses_no_same_slope_no_zero_s2 <- sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "sensory")
Joining, by = c("subject", "cond_per_block")
Absent lapses no same slope no zero d
fun_sym_absent_lapses_no_same_slope_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, -p[1], p[3]))))
fit_sym_absent_lapses_no_same_slope_d2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_no_same_slope_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_no_same_slope_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_no_same_slope_d2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses no same slope no zero vs absent lapses no same slope no zero d
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d2 <- model_selection_lrt(
fit_sym_absent_lapses2$logliks,
fit_sym_absent_lapses_no_same_slope_d2$logliks)
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_absent_lapses_no_same_slope_no_zero_full2 <- sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
anti_join(best_sym_absent_lapses_no_same_slope_no_zero_s2, by = c("subject", "cond_per_block")) %>%
filter(best == "first") %>%
select(subject, cond_per_block) %>%
mutate(best = "full")
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_sym_absent_lapses_no_same_slope_no_zero_d2 <- sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d2 %>%
semi_join(best_sym_absent_lapses_no_same_slope2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "decision")
Joining, by = c("subject", "cond_per_block")
Absent lapses same slope zero
fun_sym_absent_lapses_same_slope_zero2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]))))
fit_sym_absent_lapses_same_slope_zero2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_same_slope_zero2,
xmin = -3, xmax = 3,
parini = list(pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_same_slope_zero2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_same_slope_zero2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses same slope no zero vs absent lapses same slope zero
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero2 <- model_selection_lrt(
fit_sym_absent_lapses_same_slope2$logliks,
fit_sym_absent_lapses_same_slope_zero2$logliks)
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero2 %>%
semi_join(best_sym_absent_lapses_same_slope2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_absent_lapses_same_slope_no_zero2 <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero2 %>%
semi_join(best_sym_absent_lapses_same_slope2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
### Add to s vs d
best_absent_lapses_same_slope_zero2 <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero2 %>%
semi_join(best_sym_absent_lapses_same_slope2) %>%
filter(best == "second") %>%
select(subject, cond_per_block) %>%
mutate(best = "zero")
Joining, by = c("subject", "cond_per_block")
Absent lapses same slope no zero s
fun_sym_absent_lapses_same_slope_no_zero_s2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]))))
fit_sym_absent_lapses_same_slope_no_zero_s2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_same_slope_no_zero_s2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_same_slope_no_zero_s2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_same_slope_no_zero_s2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses same slope no zero vs absent lapses same slope no zero s
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s2 <- model_selection_lrt(
fit_sym_absent_lapses_same_slope2$logliks,
fit_sym_absent_lapses_same_slope_no_zero_s2$logliks)
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s2 %>%
semi_join(best_absent_lapses_same_slope_no_zero2) %>%
group_by(best) %>%
count()
Joining, by = c("subject", "cond_per_block")
best_absent_lapses_same_slope_no_zero_no_s2 <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s2 %>%
semi_join(best_absent_lapses_same_slope_no_zero2) %>%
filter(best == "first") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
best_absent_lapses_same_slope_no_zero_s2 <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s2 %>%
semi_join(best_absent_lapses_same_slope_no_zero2) %>%
filter(best == "second") %>%
select(subject, cond_per_block)
Joining, by = c("subject", "cond_per_block")
Absent lapses same slope no zero d
fun_sym_absent_lapses_same_slope_no_zero_d2 <- dat2 %>%
distinct(references) %>%
bind_cols(tibble(fun = c(
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]),
function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, -p[1], p[2]))))
fit_sym_absent_lapses_same_slope_no_zero_d2 <- quickpsy(dat2,
orientation, response,
grouping = .(subject, references, cond_per_block),
fun = fun_sym_absent_lapses_same_slope_no_zero_d2,
xmin = -3, xmax = 3,
parini = list(pini_origin, pini_scale),
bootstrap = "none")
ggplot() + facet_wrap(subject ~ cond_per_block, ncol = 6) +
geom_point(data = fit_sym_absent_lapses_same_slope_no_zero_d2$averages,
aes(x = orientation, y = prob, color = references)) +
geom_line(data = fit_sym_absent_lapses_same_slope_no_zero_d2$curves,
aes(x = x, y = y, color = references, lty = "all")) +
theme_grey() + theme(legend.position = "top")

Absent lapses same slope no zero vs absent lapses same slope no zero d
Add all best
best2 <- best_sym_no_two_guess_same_slope_zero2 %>%
bind_rows(best_sym_no_two_guess_same_slope_no_zero_full2) %>%
bind_rows(best_sym_guess_same_slope_no_zero_full2) %>%
bind_rows(best_sym_same_guess_no_same_slope_zero2) %>%
bind_rows(best_sym_same_guess_no_same_slope_no_zero_s2) %>%
bind_rows(best_sym_same_guess_same_slope_no_zero_full2) %>%
bind_rows(best_sym_same_guess_same_slope_no_zero_s2) %>%
bind_rows(best_sym_absent_lapses_no_same_slope_no_zero_s2) %>%
bind_rows(best_sym_absent_lapses_no_same_slope_no_zero_full2) %>%
bind_rows(best_sym_absent_lapses_no_same_slope_no_zero_d2) %>%
bind_rows(best_absent_lapses_same_slope_zero2) %>%
bind_rows(best_absent_lapses_same_slope_no_zero_no_s2) %>%
bind_rows(best_absent_lapses_same_slope_no_zero_s2)
sym_averages_s_vs_d_best2 <- sym_averages_s_vs_d2 %>%
left_join(best2)
Joining, by = c("subject", "cond_per_block")
sym_curves_s_vs_d_best2 <- sym_curves_s_vs_d2 %>%
left_join(best2)
Joining, by = c("subject", "cond_per_block")
sym_par_s_vs_d_best2 <- sym_par_s_vs_d2 %>%
left_join(best2)
Joining, by = c("subject", "cond_per_block")
sym_par_s_vs_d_best_long2 <- sym_par_s_vs_d_best2 %>%
select(subject, cond_per_block, par, best, parn) %>%
spread(parn, par)
sym_par_s_vs_d_best_abs2 <- sym_par_s_vs_d_best2 %>%
filter(parn == "p1" | parn == "p2") %>%
mutate(parn = if_else(parn == "p1",
"Sensory\nbias", "Decisional\nbias"),
abs_par = abs(par))
Save data
LS0tCnRpdGxlOiAiU3ltbWV0cmljIHRhc2sgIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgUmVhZGluZyBsaWJyYXJpZXMgYW5kIHBhcmFtZXRlcnMKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShxdWlja3BzeSkKbGlicmFyeShjb3dwbG90KQoKbGlzdC5maWxlcygiUiIsIGZ1bGwubmFtZXMgPSBUUlVFKSAlPiUgd2Fsayhzb3VyY2UpCnNvdXJjZSgiZ3JhcGhpY2FsX3BhcmFtZXRlcnMuUiIpCnNvdXJjZSgicGFyYW1ldGVycy5SIikKCmxvYWQoZmlsZSA9ICJsb2dkYXRhL2RhdDIuUkRhdGEiKQoKYGBgCgojIyMgTm8gdHdvIGd1ZXNzICAKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLnN3aWR0aD0xNX0KZnVuX3N5bV9ub190d29fZ3Vlc3MyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICsgKDEgLSBwWzVdIC0gcFs2XSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs3XSArICgxIC0gcFs3XSAtIHBbOF0pICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbNF0pKSkpCgpmaXRfc3ltX25vX3R3b19ndWVzczIgPC0gcXVpY2twc3koZGF0Miwgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX25vX3R3b19ndWVzczIsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3MyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgVHdvIGd1ZXNzCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV90d29fZ3Vlc3MyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArIHBbN10gKyAoMSAtIDIgKiBwWzVdIC0gcFs3XSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs2XSArICgxIC0gMiAqIHBbNl0gLSBwWzddKSAqIHBub3JtKHgsIHBbMV0gLSBwWzJdLCBwWzRdKSkpKQoKZml0X3N5bV90d29fZ3Vlc3MyIDwtIHF1aWNrcHN5KGRhdDIsIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV90d29fZ3Vlc3MyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fdHdvX2d1ZXNzMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV90d29fZ3Vlc3MyJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHR3byBndWVzcyB2cyB0d28gZ3Vlc3MKYGBge3J9CnN5bV9ub190d29fZ3Vlc3NfdnNfdHdvX2d1ZXNzMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzMiRsb2dsaWtzLCAKICBmaXRfc3ltX3R3b19ndWVzczIkbG9nbGlrcykgCgpzeW1fbm9fdHdvX2d1ZXNzX3ZzX3R3b19ndWVzczIgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub190d29fZ3Vlc3MyIDwtIHN5bV9ub190d29fZ3Vlc3NfdnNfdHdvX2d1ZXNzMiAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykKCmJlc3Rfc3ltX3R3b19ndWVzczIgPC0gc3ltX25vX3R3b19ndWVzc192c190d29fZ3Vlc3MyICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykKCmBgYAoKIyMjIE5vIHR3byBndWVzcyBzYW1lIHNsb3BlICAKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyArICgxIC0gcFs0XSAtIHBbNV0pICogcG5vcm0oeCwgcFsxXSArIHBbMl0sIHBbM10pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNl0gKyAoMSAtIHBbNl0gLSBwWzddKSAqIHBub3JtKHgsIHBbMV0gLSBwWzJdLCBwWzNdKSkpKQoKZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIgPC0gcXVpY2twc3koZGF0Miwgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHZzIG5vIHR3byBndWVzcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fbm9fdHdvX2d1ZXNzX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzMiRsb2dsaWtzLCAKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzKSAKCnN5bV9ub190d29fZ3Vlc3NfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUyICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3MyKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIgPC0gc3ltX25vX3R3b19ndWVzc192c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3MyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spCgpgYGAKCiMjIyBTeW0gZ3Vlc3MKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2d1ZXNzMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNV0gKyAoMSAtIDIgKiBwWzVdKSAqIHBub3JtKHgsIHBbMV0gKyBwWzJdLCBwWzNdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzZdICsgKDEgLSAyICogcFs2XSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFs0XSkpKSkKCmZpdF9zeW1fZ3Vlc3MyIDwtIHF1aWNrcHN5KGRhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2d1ZXNzMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2d1ZXNzMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ndWVzczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKCiMjIyBTeW0gZ3Vlc3MgdnMgbm8gc3ltIGd1ZXNzCmBgYHtyfQpzeW1fdHdvX2d1ZXNzX3ZzX3N5bV9ndWVzczIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3R3b19ndWVzczIkbG9nbGlrcywgCiAgZml0X3N5bV9ndWVzczIkbG9nbGlrcykgCgpzeW1fdHdvX2d1ZXNzX3ZzX3N5bV9ndWVzczIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3R3b19ndWVzczIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fZ3Vlc3MyIDwtIGJlc3Rfc3ltX3R3b19ndWVzczIKYGBgCgoKIyMjIFN5bSBzYW1lIGd1ZXNzCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNV0gKyAoMSAtIDIgKiBwWzVdKSAqIHBub3JtKHgsIHBbMV0gKyBwWzJdLCBwWzNdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzVdICsgKDEgLSAyICogcFs1XSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFs0XSkpKSkKCmZpdF9zeW1fc2FtZV9ndWVzczIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsICByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX3NhbWVfZ3Vlc3MyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzczIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3MgdnMgbm8gc2FtZSBzbG9wZQpgYGB7cn0Kc3ltX3NhbWVfZ3Vlc3NfdnNfbm9fc2FtZV9ndWVzczIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2d1ZXNzMiRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3MyJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3NfdnNfbm9fc2FtZV9ndWVzczIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub19zYW1lX2d1ZXNzMiA8LSBzeW1fc2FtZV9ndWVzc192c19ub19zYW1lX2d1ZXNzMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spCgpiZXN0X3N5bV9zYW1lX2d1ZXNzMiA8LSBzeW1fc2FtZV9ndWVzc192c19ub19zYW1lX2d1ZXNzMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKQoKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0gKyBwWzJdLCBwWzNdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzVdICsgKDEgLSAyICogcFs1XSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFszXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZTIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZTIsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgoKIyMjIE5vIHNhbWUgZ3Vlc3MgdnMgbm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fc2FtZV9ndWVzc192c19zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ndWVzczIkbG9nbGlrcywgCiAgZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzKSAKCnN5bV9zYW1lX2d1ZXNzX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MyKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIgPC0gYmVzdF9zeW1fbm9fc2FtZV9ndWVzczIKICAKYGBgCgojIyMgQWJzZW50IGxhcHNlcwpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlczIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbNF0pKSkpCgpmaXRfc3ltX2Fic2VudF9sYXBzZXMyIDwtIHF1aWNrcHN5KGRhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2Fic2VudF9sYXBzZXMyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyB2cyBubyBhYnNlbnQgbGFwc2VzCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fc2FtZV9ndWVzczIkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzMiRsb2dsaWtzKSAKCnN5bV9hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXMyICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzMiA8LSBzeW1fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3MyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykKCmJlc3Rfc3ltX2Fic2VudF9sYXBzZXMyIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXMyICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fc2FtZV9ndWVzczIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIHNhbWUgc2xvcGUgCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gMiAqIHBbNF0pICogcG5vcm0oeCwgcFsxXSArIHBbMl0sIHBbM10pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0gLSBwWzJdLCBwWzNdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyIDwtIHF1aWNrcHN5KGRhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIGFic2VudCBsYXBzZXMgdnMgbm8gYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fbm9fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzMiRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIkbG9nbGlrcykgCgpzeW1fbm9fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyIDwtIHN5bV9ub19hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyIDwtIHN5bV9ub19hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKQoKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIApgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIDAuMDEgKyAoMSAtIDIgKiAwLjAxKSAqIHBub3JtKHgsIHBbMV0gKyBwWzJdLCBwWzNdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFszXSkpKSkKCmZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgdnMgYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzMiRsb2dsaWtzLCAKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKQoKYGBgCgoKIyMjIEF2ZXJhZ2VzLCBjdXJ2ZXMgYW5kIHBhcmFtZXRlcnMgKGNoZWNraW5nKQpgYGB7cn0Kc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0MiA8LSAKICAoZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIpKQoKc3ltX2N1cnZlc19zX3ZzX2RfdGVzdDIgPC0gCiAgKGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUyJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMikpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgpgYGB7cn0Kc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0MiA8LSAKICAoZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MyKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUyJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MyKSkKCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0MiwgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gc3ltX2N1cnZlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCmBgYHtyfQpzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX3NhbWVfZ3Vlc3MyJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikpCgpzeW1fY3VydmVzX3NfdnNfZF90ZXN0MiA8LSAKICAoZml0X3N5bV9zYW1lX2d1ZXNzMiRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyKSkKCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0MiwgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gc3ltX2N1cnZlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCmBgYHtyfQpzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikpCgoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaykgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgpgYGB7cn0Kc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0MiA8LSAKICAoZml0X3N5bV9hYnNlbnRfbGFwc2VzMiRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpKQoKc3ltX2N1cnZlc19zX3ZzX2RfdGVzdDIgPC0gCiAgKGZpdF9zeW1fYWJzZW50X2xhcHNlczIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikpCgoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaykgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04fQpzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyIDwtIAogIChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikpCgoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaykgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdDIsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QyLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQXZlcmFnZXMsIGN1cnZlcyBhbmQgcGFyYW1ldGVycyAKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1fQpzeW1fYXZlcmFnZXNfc192c19kMiA8LSAKICAoZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUyJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fc2FtZV9ndWVzczIpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzMiRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXMyJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyKSkpCgpzeW1fY3VydmVzX3NfdnNfZDIgPC0gCiAgKGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUyJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMikpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZTIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fc2FtZV9ndWVzczIpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzMiRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyKSkpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlMiRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyKSkpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fYWJzZW50X2xhcHNlczIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikpKQoKc3ltX3Bhcl9zX3ZzX2QyIDwtIAogIChmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiRwYXIgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUyJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MyKSkpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fc2FtZV9ndWVzczIkcGFyICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZTIkcGFyICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXMyJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIpKSkKCgpzeW1fcGFyX3NfdnNfZF9sb25nMiA8LSBzeW1fcGFyX3NfdnNfZDIgJT4lIAogIHNwcmVhZChwYXJuLCBwYXIpIAoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaykgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2QyLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBzeW1fY3VydmVzX3NfdnNfZDIsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV92bGluZShkYXRhID0gc3ltX3Bhcl9zX3ZzX2RfbG9uZzIsCiAgICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBwMSwgbHR5ID0gInAxIikpICsKICAgIGdlb21fdmxpbmUoZGF0YSA9IHN5bV9wYXJfc192c19kX2xvbmcyLCAKICAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IHAxICsgcDIsIGx0eSA9ICJwMSArcDIiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgemVybwpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzJdICsgKyAoMSAtIHBbMl0gLSBwWzNdKSAqIHBub3JtKHgsIDAsIHBbMV0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIHBbNF0gLSBwWzVdKSAqIHBub3JtKHgsIDAsIHBbMV0pKSkpCgpmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yIDwtIHF1aWNrcHN5KGRhdDIsIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBObyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvIHZzIG5vIHR3byBndWVzcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzLCAKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yJGxvZ2xpa3MpIAoKc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIgPC0gc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yIDwtIHN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiemVybyIpCgpgYGAKCiMjIyBObyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZSBzICAKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3MyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICsgKDEgLSBwWzNdIC0gcFs0XSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzVdICsgKDEgLSBwWzVdIC0gcFs2XSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSkpKQoKZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9zMiA8LSBxdWlja3BzeShkYXQyLCBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfczIsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3MyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3MyJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHR3byBndWVzcyBzYW1lIHNsb3BlIHZzIG5vIHR3byBndWVzcyBzYW1lIHNsb3BlIHMKYGBge3J9CnN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9zMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUyJGxvZ2xpa3MsIAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfczIkbG9nbGlrcykgCgpzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfczIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgZCAgCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbM10gKyArICgxIC0gcFszXSAtIHBbNF0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICgxIC0gcFs1XSAtIHBbNl0pICogcG5vcm0oeCwgLXBbMV0sIHBbMl0pKSkpCgpmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QyIDwtIHF1aWNrcHN5KGRhdDIsIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZDIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZDIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgdnMgbm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgZApgYGB7cn0Kc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZTIkbG9nbGlrcywgCiAgZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kMiRsb2dsaWtzKSAKCnN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19mdWxsMiA8LSBzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZDIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spICU+JSAKICBtdXRhdGUoYmVzdCA9ICJmdWxsIikKCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFsyXSArICgxIC0gMiAqIHBbMl0pICogcG5vcm0oeCwgMCwgcFsxXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgMCwgcFsxXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIHZzIG5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvCmBgYHtyfQpzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV92c19zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZTIkbG9nbGlrcywgCiAgZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yJGxvZ2xpa3MpIAoKc3ltX2d1ZXNzX3NhbWVfc2xvcGVfdnNfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MyKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIgPC0gc3ltX2d1ZXNzX3NhbWVfc2xvcGVfdnNfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19zYW1lX2d1ZXNzMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spIAoKCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBzCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3MyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gMiAqIHBbNF0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9zMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3MyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX3MyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIG5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHMKYGBge3J9CnN5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfczIkbG9nbGlrcykgCgpzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fbm9fczIgPC0gc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykgCgpiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgPC0gc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spIAoKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIGQKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZDIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzRdICsgKDEgLSAyICogcFs0XSkgKiBwbm9ybSh4LCAtcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9kMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX2QyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX2QyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZDIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIG5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3J9CnN5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZDIkbG9nbGlrcykgCgpzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbDIgPC0gc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZDIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykgJT4lIAogIG11dGF0ZShiZXN0ID0gImZ1bGwiKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSB6ZXJvCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX3plcm8yIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgMCwgcFsxXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgMCwgcFsyXSkpKSkKCmZpdF9zeW1fc2FtZV9ndWVzc196ZXJvMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX3plcm8yLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9zY2FsZSwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3NfemVybzIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc196ZXJvMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIHplcm8KYGBge3J9CnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfemVybzIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3NhbWVfZ3Vlc3MyJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc196ZXJvMiRsb2dsaWtzKSAKCnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfemVybzIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm8gPC0gc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV96ZXJvMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX3plcm8yIDwtIHN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfemVybzIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spICU+JSAKICBtdXRhdGUoYmVzdCA9ICJ6ZXJvIikKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIG5vIHNhbWUgc2xvcGUgbm8gemVybyBzCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fczIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzRdICsgKDEgLSAyICogcFs0XSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzRdICsgKDEgLSAyICogcFs0XSkgKiBwbm9ybSh4LCBwWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fczIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fc2FtZV9ndWVzc19ub196ZXJvX3MyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fczIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX3MyJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCgojIyMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzMiRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfbm9femVyb19zMiRsb2dsaWtzKSAKCnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm8pICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3Nfbm9femVyb19kMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0sIHBbMl0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIC1wWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fZDIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fZDIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QyJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBTYW1lIGd1ZXNzIG5vIHNhbWUgc2xvcGUgbm8gemVybyB2cyBTYW1lIGd1ZXNzIG5vIHNhbWUgc2xvcGUgbm8gemVybyBkCmBgYHtyfQpzeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZDIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3NhbWVfZ3Vlc3MyJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QyJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX2QyJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIHN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19kMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykgJT4lICAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCgpgYGAKCiMjIyBTeW0gc2FtZSBndWVzcyBzYW1lIHNsb3BlIHplcm8gCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzJdICsgKDEgLSAyICogcFsyXSkgKiBwbm9ybSh4LCAwLCBwWzFdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzJdICsgKDEgLSAyICogcFsyXSkgKiBwbm9ybSh4LCAwLCBwWzFdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfemVybzIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvCmBgYHtyfQpzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8yJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIgPC0gc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAKCgpgYGAKCiMjIyBTeW0gc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHMKYGBge3J9CnN5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlMiRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MyJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MyICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgLXBbMV0sIHBbMl0pKSkpCgpmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtIHF1aWNrcHN5KGRhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgU2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gZApgYGB7cn0Kc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUyJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZDIkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZDIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19mdWxsMiA8LSBzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiZnVsbCIpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykgJT4lIAogIG11dGF0ZShiZXN0ID0gInNlbnNvcnkiKQoKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIHplcm8gCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfemVybzIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAwLCBwWzFdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAwLCBwWzJdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfemVybzIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3plcm8yLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9zY2FsZSwgcGluaV9zY2FsZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IGNvbmRfcGVyX2Jsb2NrLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3plcm8yJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlICAgdnMgYWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIHplcm8gCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fYWJzZW50X2xhcHNlczIkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfemVybzIkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIG5vIHNhbWUgc2xvcGUgbm8gemVybyBzCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfczIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfczIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3MyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9zMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfczIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHZzIGFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHMKYGBge3J9CnN5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fYWJzZW50X2xhcHNlczIkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfczIkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fbm9fczIgPC0gc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MyICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spICU+JSAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9kMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIDAuMDEgKyAoMSAtIDIgKiAwLjAxKSAqIHBub3JtKHgsIHBbMV0sIHBbMl0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIDAuMDEgKyAoMSAtIDIgKiAwLjAxKSAqIHBub3JtKHgsIC1wWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfZDIgPC0gcXVpY2twc3koZGF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHJlZmVyZW5jZXMsIGNvbmRfcGVyX2Jsb2NrKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9kMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfZDIkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHZzIGFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3J9CnN5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19kMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fYWJzZW50X2xhcHNlczIkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfZDIkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZDIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZTIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbDIgPC0gc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX2QyICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlMikgJT4lIAogIGFudGlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19zMiwgYnkgPSBjKCJzdWJqZWN0IiwgImNvbmRfcGVyX2Jsb2NrIikpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiZnVsbCIpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19kMiA8LSBzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZDIgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUyKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spICU+JSAKICBtdXRhdGUoYmVzdCA9ICJkZWNpc2lvbiIpCgpgYGAKCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIHplcm8KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiA8LSAgZGF0MiAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIDAuMDEgKyAoMSAtIDIgKiAwLjAxKSAqIHBub3JtKHgsIDAsIHBbMV0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIDAuMDEgKyAoMSAtIDIgKiAwLjAxKSAqIHBub3JtKHgsIDAsIHBbMV0pKSkpCgpmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybzIsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybzIkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX3plcm8yJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgbm8gemVybyB2cyBhYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgemVybwpgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlMiRsb2dsaWtzLCAKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiRsb2dsaWtzKSAKCnN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybzIgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybzIgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybzIgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvMiAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaykgJT4lIAogIG11dGF0ZShiZXN0ID0gInplcm8iKQoKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fczIgPC0gIGRhdDIgJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiA8LSBxdWlja3BzeShkYXQyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgcmVmZXJlbmNlcywgY29uZF9wZXJfYmxvY2spLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gY29uZF9wZXJfYmxvY2ssIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUyJGxvZ2xpa3MsIAogIGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fczIkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fczIgJT4lCiAgc2VtaV9qb2luKGJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fbm9fczIgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyICU+JSAKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAKCgpiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiAlPiUgCiAgc2VtaV9qb2luKGJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spIAoKCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtICBkYXQyICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgLXBbMV0sIHBbMl0pKSkpCgpmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QyIDwtIHF1aWNrcHN5KGRhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCByZWZlcmVuY2VzLCBjb25kX3Blcl9ibG9jayksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QyLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiBjb25kX3Blcl9ibG9jaywgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QyJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QyJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgbm8gemVybyB2cyBhYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgbm8gemVybyBkCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fZDIgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZTIkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19kMiRsb2dsaWtzKSAKCnN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19kMiAlPiUKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fbm9fczIgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyICU+JSAKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybzIpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIGNvbmRfcGVyX2Jsb2NrKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiZnVsbCIpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zMiAlPiUgCiAgc2VtaV9qb2luKGJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm8yKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgY29uZF9wZXJfYmxvY2spICU+JSAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCgoKYGBgCgoKIyMjIyBBZGQgYWxsIGJlc3QKYGBge3J9CmJlc3QyIDwtIGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8yICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19mdWxsMikgJT4lIAogIGJpbmRfcm93cyhiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbDIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX3plcm8yKSAlPiUgIAogIGJpbmRfcm93cyhiZXN0X3N5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zMikgJT4lICAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbDIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fczIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fczIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbDIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZDIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybzIpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19ub19zMikgJT4lIAogIGJpbmRfcm93cyhiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MyKSAKCgpzeW1fYXZlcmFnZXNfc192c19kX2Jlc3QyIDwtICBzeW1fYXZlcmFnZXNfc192c19kMiAlPiUKICBsZWZ0X2pvaW4oYmVzdDIpIAogIApzeW1fY3VydmVzX3NfdnNfZF9iZXN0MiA8LSBzeW1fY3VydmVzX3NfdnNfZDIgJT4lIAogIGxlZnRfam9pbihiZXN0MikKCnN5bV9wYXJfc192c19kX2Jlc3QyIDwtIHN5bV9wYXJfc192c19kMiAlPiUgCiAgbGVmdF9qb2luKGJlc3QyKSAKCnN5bV9wYXJfc192c19kX2Jlc3RfbG9uZzIgPC0gc3ltX3Bhcl9zX3ZzX2RfYmVzdDIgJT4lIAogIHNlbGVjdChzdWJqZWN0LCBjb25kX3Blcl9ibG9jaywgcGFyLCBiZXN0LCBwYXJuKSAlPiUgCiAgc3ByZWFkKHBhcm4sIHBhcikgCgpzeW1fcGFyX3NfdnNfZF9iZXN0X2FiczIgPC0gc3ltX3Bhcl9zX3ZzX2RfYmVzdDIgJT4lIAogICAgICAgICAgICAgIGZpbHRlcihwYXJuID09ICJwMSIgfCBwYXJuID09ICJwMiIpICU+JSAKICAgICAgICAgICAgICBtdXRhdGUocGFybiA9IGlmX2Vsc2UocGFybiA9PSAicDEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2Vuc29yeVxuYmlhcyIsICJEZWNpc2lvbmFsXG5iaWFzIiksCiAgICAgICAgICAgICAgICAgICAgIGFic19wYXIgPSBhYnMocGFyKSkKCmBgYAoKIyMjIFNhdmUgZGF0YQpgYGB7cn0Kc2F2ZShzeW1fYXZlcmFnZXNfc192c19kX2Jlc3QsIGZpbGUgPSAibG9nZGF0YS9zeW1fYXZlcmFnZXNfc192c19kX2Jlc3QyLlJkYXRhIikKc2F2ZShzeW1fY3VydmVzX3NfdnNfZF9iZXN0LCBmaWxlID0gImxvZ2RhdGEvc3ltX2N1cnZlc19zX3ZzX2RfYmVzdDIuUkRhdGEiKQpzYXZlKHN5bV9wYXJfc192c19kX2Jlc3QsIGZpbGUgPSAibG9nZGF0YS9zeW1fcGFyX3NfdnNfZF9iZXN0X2xvbmcyLlJEYXRhIikKc2F2ZShzeW1fcGFyX3NfdnNfZF9iZXN0X2xvbmcsIGZpbGUgPSAibG9nZGF0YS9zeW1fcGFyX3NfdnNfZF9iZXN0X2FiczIuUkRhdGEiKQoKYGBgCgoKCg==